#include "zen_vap_activity.h"
#include "zen_vap_action.h"
#include "zen_vap_combination.h"
#include "zen_app.h"
#include "zen_ticker.h"
#include "zen_log.h"
#include <vector>
#include <mutex>
#include <queue>
#include <map>

namespace Zen { namespace Vap {

	class Activity_i : public Activity {
	protected:

		Size2 m_real_size;

		std::shared_ptr<Node> m_root_node;
		std::shared_ptr<RootDelegate> m_delegate;
		std::shared_ptr<TouchDispatcher> m_touch_dispatcher;
		std::shared_ptr<ActionDispatcher> m_action_dispatcher;
		Color4f m_color;

		double m_running_duration; // running duration
		std::chrono::microseconds m_start_time;

	public:
		static std::shared_ptr<Activity_i> Get();

		Activity_i();

		~Activity_i();

		void clean();

	public: // override
		virtual void setDelegate(std::shared_ptr<RootDelegate> delegate) override;
		virtual std::shared_ptr<RootDelegate> getDelegate() override;
		virtual Size2 getRealViewSize() override;
		virtual void setBackgroundColor(Color4f const & color) override;
		virtual Color4f getBackgroundColor() override;
		virtual double getRunningTime() override;
		virtual double getTotalTime() override;

//		virtual void replaceRootNode(std::shared_ptr<Node> node) override;
		virtual std::shared_ptr<Node> getRootNode() override;

		Zen::Vap::TouchDispatcher *getTouchDispatcher() override {
			return m_touch_dispatcher.get();
		}

		Zen::Vap::ActionDispatcher *getActionDispather() override {
			return m_action_dispatcher.get();
		}

//		virtual TouchDispatcher *


	public:
		virtual void onLaunch(Zen::Size2 view_size) override;

		virtual void onResize(Zen::Size2 view_size) override;

		virtual void onExit() override;

		virtual void onPause() override;

		virtual void onResume() override;

		virtual void onUpdate() override;

		virtual void onDraw() override;

		virtual void onTouchDown(AppTouch touch) override;

		virtual void onTouchMove(AppTouch touch) override;

		virtual void onTouchUp(AppTouch touch) override;

		virtual void onTouchCancel(AppTouch touch) override;

	};

}}


namespace Zen { namespace Vap {

	void Activity_i::onLaunch(Zen::Size2 view_size)
	{
    ZEN_DEBUG_LOG(0);

		this->setBackgroundColor(Color4f(0x333355ff));

		Helper::Get()->initRender();

		m_real_size = view_size;
		
		m_running_duration = 0.0; //std::chrono::microseconds::zero();
		
		if(m_delegate) m_delegate->onLaunch(m_real_size);
	}

	void Activity_i::onResize(Zen::Size2 view_size)
	{
    ZEN_DEBUG_LOG(0);

		m_real_size = view_size;
		if(m_delegate) m_delegate->onResize(m_real_size);
	}

	void Activity_i::onExit()
	{
    ZEN_DEBUG_LOG(0);

		if(m_delegate) m_delegate->onExit();
	}

	void Activity_i::onPause()
	{
    ZEN_DEBUG_LOG(0);

		if(m_delegate) m_delegate->onPause();
	}

	void Activity_i::onResume()
	{
    ZEN_DEBUG_LOG(0);

		if(m_delegate) m_delegate->onResume();
	}

	void Activity_i::onUpdate()
	{
		this->clean();

		auto interval = 1.f / App::Get()->getFramesPerSecond(); // m_ticker.tick();

		m_running_duration += interval;

		m_action_dispatcher->onUpdate(interval);

		if(m_delegate) m_delegate->onUpdate();
		
	}

	void Activity_i::onDraw()
	{
		this->clean();

		if(m_delegate) m_delegate->onDraw();

		if(1)
		{
			m_root_node->ready();
			RenderGuard r;
			m_root_node->draw();
		}
		
		this->clean();
	}

	void Activity_i::onTouchDown(AppTouch touch)
	{
		this->clean();

		if(m_delegate) m_delegate->onTouchDown(touch);

		m_touch_dispatcher->onTouchDown(touch);
	}

	void Activity_i::onTouchMove(AppTouch touch)
	{
		this->clean();

		if(m_delegate) m_delegate->onTouchMove(touch);

		m_touch_dispatcher->onTouchMove(touch);
	}

	void Activity_i::onTouchUp(AppTouch touch)
	{
		this->clean();

		if(m_delegate) m_delegate->onTouchUp(touch);

		m_touch_dispatcher->onTouchUp(touch);
	}

	void Activity_i::onTouchCancel(AppTouch touch)
	{
		this->clean();

		if(m_delegate) m_delegate->onTouchCancel(touch);

		m_touch_dispatcher->onTouchCancel(touch);
	}
}}

namespace Zen { namespace Vap {

	std::shared_ptr<Activity> Activity::Get()
	{
		return Activity_i::Get();
	}
	std::shared_ptr<Activity_i> Activity_i::Get()
	{
		static auto root = std::make_shared<Activity_i>();
		return root;
	}
	Activity_i::Activity_i()
	{
		m_root_node = std::make_shared<Combination>();
		m_touch_dispatcher = std::make_shared<TouchDispatcher>();
		m_action_dispatcher = std::make_shared<ActionDispatcher>();
	}

	Activity_i::~Activity_i()
	{
		m_root_node.reset();
	}

	void Activity_i::setDelegate(std::shared_ptr<RootDelegate> delegate)
	{
		m_delegate = delegate;
	}

	void Activity_i::setBackgroundColor(Color4f const & color)
	{
		m_color = color;
		Helper::Get()->setClearColor(color);
	}

	Color4f Activity_i::getBackgroundColor()
	{
		return m_color;
	}
	
	Size2 Activity_i::getRealViewSize()
	{
		return m_real_size;
	}

	std::shared_ptr<Node> Activity_i::getRootNode()
	{
		return m_root_node;
	}
	double Activity_i::getRunningTime()
	{
		return m_running_duration;
	}
	double Activity_i::getTotalTime()
	{
		return Zen::ToSeconds(Now() - m_start_time);
	}
	std::shared_ptr<RootDelegate> Activity_i::getDelegate()
	{
		return m_delegate;
	}

	void Activity_i::clean()
	{
	}
}}

/**
 @ref part of node
 */

namespace Zen { namespace Vap {

}}
